﻿
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class ShootCube : UdonSharpBehaviour
{
    /// <summary>
    /// 炮台脚本：随机扫描（红色探照灯），照到玩家后停住计时，3秒内未离开则激光锁定并发射物体。
    /// 不创建资产，通过检视器引用场景中已有对象与组件。
    /// </summary>
    [Header("扫描/探照灯")]
    [Tooltip("Spot 光源（探照灯），会被设置为红色用于扫描与警示")]
    public Light spotLight; // 需为Spot类型
    [Tooltip("旋转与指向的枢轴，通常与 SpotLight 同一物体。为空则在初始化时使用 SpotLight 的 Transform")]
    public Transform scanPivot; // 旋转与发射的枢轴（通常与spotLight同一物体）
    [Tooltip("扫描最大半径（米）。随机目标会在该半径的水平范围内生成")]
    public float scanRadius = 20f; // 随机扫描最大距离
    [Tooltip("扫描旋转速度（度/秒）")]
    public float scanTurnSpeedDegPerSec = 90f; // 每秒转向度数
    [Tooltip("随机扫描目标的刷新间隔（秒）")]
    public float newPointInterval = 2f; // 每隔多久随机一个目标点
    [Tooltip("用于视线遮挡判断的层（命中表示被遮挡，玩家不可见）")]
    public LayerMask obstructionMask = -1; // 视线阻挡层，默认全选（除了玩家层）

    [Header("检测")]
    [Tooltip("玩家被探照灯照到后，需要持续保持的时间（秒）才会进入激光锁定与开火")]
    public float requiredHoldSeconds = 3f; // 玩家需在光束内持续的时间
    [Tooltip("覆盖 Spot 光的视角（度）。小于等于 0 时，使用 spotLight.spotAngle 作为有效视角")]
    public float fieldOfViewDegOverride = -1f; // 可覆盖spotLight.spotAngle（<=0 则使用spotAngle）
    [Tooltip("视线判定的末端容忍距离（米）。命中距离若接近目标末端（视为打到玩家身体）则认为无遮挡")]
    [Range(0f, 1f)] public float losEndAllowance = 0.25f;

    [Header("激光与发射")]
    [Tooltip("红色激光的 LineRenderer。需在场景中预设材质与宽度，positionCount 应为 2")]
    public LineRenderer laserLine; // 预先在场景中配置材质与宽度
    [Tooltip("发射口 Transform（子弹/物体从这里射出）。为空则使用 scanPivot 位置与朝向")]
    public Transform muzzlePoint; // 发射口
    [Tooltip("对象池：将要发射的刚体列表，会循环取用。需要在场景中事先放置")]
    public Rigidbody[] projectilePool; // 物体对象池（场景中已有）
    [Tooltip("发射初速度（米/秒）")]
    public float projectileSpeed = 20f;
    [Tooltip("激光持续指向玩家的时间（秒）")]
    public float laserDurationSeconds = 3f;
    [Tooltip("激光结束后的等待冷却时间（秒），其间关闭激光与探照灯")]
    public float cooldownAfterLaserSeconds = 5f;
    [Tooltip("激光线宽（米）")]
    public float laserWidth = 0.02f;

    [Header("瞄准设置")]
    [Tooltip("是否瞄准玩家身体而不是摄像机/头部")]
    public bool aimAtBody = true;
    [Tooltip("优先使用的人形骨骼（如可用）来确定身体瞄准点")]
    public HumanBodyBones preferredBodyBone = HumanBodyBones.Chest;
    [Tooltip("当骨骼不可用时，使用玩家位置 + 该高度偏移作为身体瞄准点（米）")]
    public float bodyAimHeightOffset = 1.0f;

    [Header("命中与伤害")]
    [Tooltip("与生命系统联动的脚本引用。仅本地玩家被判定命中时会被清零生命值")]
    public WorldHealth worldHealth;
    [Tooltip("是否启用基于距离的本地玩家命中判定（无需依赖子弹碰撞体脚本）")]
    public bool killOnProjectileHit = true;
    [Tooltip("命中半径（米）：当子弹与本地玩家身体瞄准点的距离小于该值时判定为命中")]
    public float projectileHitRadius = 0.35f;
    [Tooltip("命中后是否禁用该子弹对象（需要本地拥有权）")]
    public bool deactivateProjectileOnHit = true;
    [Tooltip("子弹存活时间（秒）。用于超时停止命中检测，避免无限追踪。<=0 表示不限制")]
    public float projectileLifeSeconds = 8f;

    [Header("黄灯音效设置")]
    [Tooltip("黄灯状态时播放的音频源 - 将场景中的AudioSource组件拖拽到此处")]
    public AudioSource yellowLightAudioSource;
    [Tooltip("启用黄灯音效 - 是否在灯光变黄时播放音效")]
    public bool enableYellowLightAudio = true;
    [Tooltip("黄灯音效音量 - 控制黄灯音效的音量大小")]
    [Range(0f, 1f)] public float yellowLightVolume = 0.8f;
    [Tooltip("黄灯音效最大听音范围 - 音效能够被听到的最大距离（米）")]
    [Range(1f, 50f)] public float yellowLightAudioMaxDistance = 15f;
    [Tooltip("黄灯音效最小听音范围 - 音效开始衰减的最小距离（米）")]
    [Range(0.1f, 10f)] public float yellowLightAudioMinDistance = 1f;
    [Tooltip("显示黄灯音效范围 - 是否在Scene视图中显示音效范围的可视化线框")]
    public bool showYellowLightAudioRange = true;
    [Tooltip("黄灯音效范围颜色 - 仅编辑器中音效范围可视化的颜色")]
    public Color yellowLightAudioRangeColor = new Color(1f, 1f, 0f, 0.3f);

    [Header("发射音效设置")]
    [Tooltip("发射音效音频源 - 当子弹被发射时播放的AudioSource组件")]
    public AudioSource fireAudioSource;
    [Tooltip("启用发射音效 - 是否在发射子弹时播放音效")]
    public bool enableFireAudio = true;
    [Tooltip("发射音效音量 - 控制发射音效的音量大小")]
    [Range(0f, 1f)] public float fireAudioVolume = 1.0f;
    [Tooltip("发射音效最大听音范围 - 音效能够被听到的最大距离（米）")]
    [Range(1f, 100f)] public float fireAudioMaxDistance = 30f;
    [Tooltip("发射音效最小听音范围 - 音效开始衰减的最小距离（米）")]
    [Range(0.1f, 15f)] public float fireAudioMinDistance = 2f;
    [Tooltip("显示发射音效范围 - 是否在Scene视图中显示发射音效范围的可视化线框")]
    public bool showFireAudioRange = true;
    [Tooltip("发射音效范围颜色 - 仅编辑器中发射音效范围可视化的颜色")]
    public Color fireAudioRangeColor = new Color(1f, 0.2f, 0f, 0.4f);



    [Header("命中半径可视化")]
    [Tooltip("在编辑器中选中物体时绘制命中判定球（半径=projectileHitRadius）")]
    public bool drawHitRadiusGizmo = true;
    [Tooltip("命中判定球的颜色（仅编辑器中可视化）")]
    public Color gizmoHitRadiusColor = new Color(1f, 0f, 0f, 0.35f);
    [Tooltip("非运行时用于显示命中半径的参考点（例如放到玩家大概位置）")]
    public Transform debugHitPoint;
    [Tooltip("是否同时在每个对象池子弹位置绘制命中半径球（便于观察命中判定是否触达玩家）")]
    public bool drawHitRadiusOnProjectiles = true;
    [Tooltip("子弹位置处命中半径球的颜色（仅编辑器中可视化）")]
    public Color gizmoHitRadiusOnProjectileColor = new Color(1f, 0.2f, 0.2f, 0.25f);

    [Header("阻挡层设置")]
    [Tooltip("是否自动排除玩家层和默认层")]
    public bool autoExcludePlayerLayers = true;
    [Tooltip("手动设置的阻挡层（如果autoExcludePlayerLayers为false则使用此设置）")]
    public LayerMask manualObstructionMask = -1;
    
    [Header("安全遮挡物设置")]
    [Tooltip("安全遮挡物列表：玩家躲在这些物体后面不会被发现")]
    public Transform[] safeObstacles;
    
    [Tooltip("是否启用安全遮挡物功能")]
    public bool enableSafeObstacles = false;
    
    [Header("可视化/Gizmos")]
    [Tooltip("在编辑器中选中物体时绘制扫描半径可视化")]
    public bool drawScanRadiusGizmo = true;
    [Tooltip("在编辑器中选中物体时绘制水平视角两条边界线")]
    public bool drawFovGizmo = true;
    [Tooltip("扫描半径圆环颜色（仅编辑器中可视化）")]
    public Color gizmoRadiusColor = new Color(1f, 0f, 0f, 0.5f);
    [Tooltip("视角边界线颜色（仅编辑器中可视化）")]
    public Color gizmoFovColor = new Color(1f, 0.25f, 0.25f, 0.9f);
    [Tooltip("圆环段数（越高越圆，开销略增）")]
    [Range(8, 256)] public int gizmoCircleSegments = 64;

    // 内部状态
    private const int StateScanning = 0;
    private const int StateHolding = 1;   // 玩家被照到，停止移动计时
    private const int StateLaser = 2;     // 激光锁定并持续指向
    private const int StateCooldown = 3;  // 激光结束后的冷却等待

    private int currentState = StateScanning;
    private float stateStartTime;

    private Vector3 currentScanTarget;
    private float nextRetargetTime;

    private VRCPlayerApi trackedPlayer;

    // 缓存数组以避免GC
    private VRCPlayerApi[] playersBuffer = new VRCPlayerApi[80];

    private Color originalLightColor;

    private int nextProjectileIndex;
    private bool[] projectileActiveFlags;
    private float[] projectileFiredTimes;

    // 新增：被激光锁定的玩家标签系统
    private VRCPlayerApi[] taggedPlayers = new VRCPlayerApi[10]; // 最多支持10个被标记的玩家
    private int taggedPlayerCount = 0;

    // 黄灯音效状态
    private bool isYellowLightAudioPlaying = false; // 黄灯音效是否正在播放
    
    // 发射音效状态  
    private bool isFireAudioPlaying = false; // 发射音效是否正在播放

    private void OnEnable()
    {
        InitializeIfNeeded();
        EnterScanning();
    }

    private void Start()
    {
        InitializeIfNeeded();
        EnterScanning();
    }

    private void InitializeIfNeeded()
    {
        // 设置阻挡层掩码
        if (autoExcludePlayerLayers)
        {
            // 自动排除玩家层（第8层）和默认层（第0层）
            // 这样可以确保射线检测不会检测到玩家本身
            obstructionMask = ~((1 << 8) | (1 << 0)); // 排除玩家层和默认层
        }
        else
        {
            // 使用手动设置的阻挡层
            obstructionMask = manualObstructionMask;
        }
        
        if (spotLight != null)
        {
            originalLightColor = spotLight.color;
        }

        if (scanPivot == null && spotLight != null)
        {
            scanPivot = spotLight.transform;
        }

        if (laserLine != null)
        {
            laserLine.enabled = false;
            if (laserLine.positionCount != 2) laserLine.positionCount = 2;
            laserLine.useWorldSpace = true;
            laserLine.startWidth = laserWidth;
            laserLine.endWidth = laserWidth;
            // 预设为红色
            if (laserLine.material != null && laserLine.material.HasProperty("_Color"))
            {
                laserLine.material.color = Color.red;
            }
            laserLine.startColor = Color.red;
            laserLine.endColor = Color.red;
        }

        // 初始化对象池状态跟踪
        if (projectilePool != null && projectilePool.Length > 0)
        {
            if (projectileActiveFlags == null || projectileActiveFlags.Length != projectilePool.Length)
            {
                projectileActiveFlags = new bool[projectilePool.Length];
                projectileFiredTimes = new float[projectilePool.Length];
            }
            else
            {
                for (int i = 0; i < projectileActiveFlags.Length; i++)
                {
                    projectileActiveFlags[i] = false;
                    projectileFiredTimes[i] = 0f;
                }
            }
        }

        if (muzzlePoint == null && scanPivot != null)
        {
            muzzlePoint = scanPivot;
        }

        if (scanRadius <= 0f)
        {
            scanRadius = 10f;
        }

        if (scanTurnSpeedDegPerSec <= 0f)
        {
            scanTurnSpeedDegPerSec = 90f;
        }

        if (newPointInterval <= 0f)
        {
            newPointInterval = 2f;
        }

        // 初始化黄灯音效设置
        InitializeYellowLightAudio();
        
        // 初始化发射音效设置
        InitializeFireAudio();
    }

    /// <summary>
    /// 初始化黄灯音效系统
    /// </summary>
    private void InitializeYellowLightAudio()
    {
        if (yellowLightAudioSource != null)
        {
            // 配置音频源的3D音效设置
            yellowLightAudioSource.volume = yellowLightVolume;
            yellowLightAudioSource.spatialBlend = 1.0f; // 设置为3D音效
            yellowLightAudioSource.rolloffMode = AudioRolloffMode.Linear; // 线性衰减
            yellowLightAudioSource.minDistance = yellowLightAudioMinDistance;
            yellowLightAudioSource.maxDistance = yellowLightAudioMaxDistance;
            yellowLightAudioSource.loop = false; // 不循环播放，只播放一次
            yellowLightAudioSource.playOnAwake = false; // 不在唤醒时播放
            
            // 确保音效不在开始时播放
            if (yellowLightAudioSource.isPlaying)
            {
                yellowLightAudioSource.Stop();
            }
        }
        
        isYellowLightAudioPlaying = false;
    }

    /// <summary>
    /// 播放黄灯音效 - 只在黄灯状态开始时播放一次
    /// </summary>
    private void PlayYellowLightAudio()
    {
        if (!enableYellowLightAudio || yellowLightAudioSource == null || isYellowLightAudioPlaying)
        {
            return;
        }

        // 更新音频设置（防止运行时修改）
        yellowLightAudioSource.volume = yellowLightVolume;
        yellowLightAudioSource.minDistance = yellowLightAudioMinDistance;
        yellowLightAudioSource.maxDistance = yellowLightAudioMaxDistance;

        // 播放音效
        yellowLightAudioSource.Play();
        isYellowLightAudioPlaying = true;
    }

    /// <summary>
    /// 停止黄灯音效 - 在黄灯状态结束时立即停止
    /// </summary>
    private void StopYellowLightAudio()
    {
        if (yellowLightAudioSource != null && isYellowLightAudioPlaying)
        {
            yellowLightAudioSource.Stop();
            isYellowLightAudioPlaying = false;
        }
    }

    /// <summary>
    /// 初始化发射音效系统
    /// </summary>
    private void InitializeFireAudio()
    {
        if (fireAudioSource != null)
        {
            // 配置音频源的3D音效设置
            fireAudioSource.volume = fireAudioVolume;
            fireAudioSource.spatialBlend = 1.0f; // 设置为3D音效
            fireAudioSource.rolloffMode = AudioRolloffMode.Linear; // 线性衰减
            fireAudioSource.minDistance = fireAudioMinDistance;
            fireAudioSource.maxDistance = fireAudioMaxDistance;
            fireAudioSource.loop = false; // 不循环播放，只播放一次
            fireAudioSource.playOnAwake = false; // 不在唤醒时播放
            
            // 确保音效不在开始时播放
            if (fireAudioSource.isPlaying)
            {
                fireAudioSource.Stop();
            }
        }
        
        isFireAudioPlaying = false;
    }

    /// <summary>
    /// 播放发射音效 - 在发射子弹时播放一次
    /// </summary>
    private void PlayFireAudio()
    {
        if (!enableFireAudio || fireAudioSource == null)
        {
            return;
        }

        // 更新音频设置（防止运行时修改）
        fireAudioSource.volume = fireAudioVolume;
        fireAudioSource.minDistance = fireAudioMinDistance;
        fireAudioSource.maxDistance = fireAudioMaxDistance;

        // 播放音效
        fireAudioSource.Play();
        isFireAudioPlaying = true;
    }

    private void Update()
    {
        if (scanPivot == null || spotLight == null)
        {
            return;
        }

        // 子弹命中检测（本地）
        TickProjectileHitDetection();

        switch (currentState)
        {
            case StateScanning:
                TickScanning();
                break;
            case StateHolding:
                TickHolding();
                break;
            case StateLaser:
                TickLaser();
                break;
            case StateCooldown:
                TickCooldown();
                break;
        }
    }

    // 新增：检查玩家是否被标记
    private bool IsPlayerTagged(VRCPlayerApi player)
    {
        if (player == null || !player.IsValid())
        {
            return false;
        }
        
        for (int i = 0; i < taggedPlayerCount; i++)
        {
            if (taggedPlayers[i] != null && taggedPlayers[i].IsValid() && 
                taggedPlayers[i].playerId == player.playerId)
            {
                return true;
            }
        }
        return false;
    }

    // 新增：添加玩家到标记列表
    private void AddTaggedPlayer(VRCPlayerApi player)
    {
        if (player == null || !player.IsValid())
        {
            return;
        }
        
        // 检查是否已经存在
        if (IsPlayerTagged(player))
        {
            return;
        }
        
        // 添加到列表
        if (taggedPlayerCount < taggedPlayers.Length)
        {
            taggedPlayers[taggedPlayerCount] = player;
            taggedPlayerCount++;
        }
    }

    // 新增：从标记列表移除玩家
    private void RemoveTaggedPlayer(VRCPlayerApi player)
    {
        if (player == null || taggedPlayerCount <= 0)
        {
            return;
        }
        
        for (int i = 0; i < taggedPlayerCount; i++)
        {
            if (taggedPlayers[i] != null && taggedPlayers[i].IsValid() && 
                taggedPlayers[i].playerId == player.playerId)
            {
                // 移除：将最后一个元素移到当前位置
                taggedPlayers[i] = taggedPlayers[taggedPlayerCount - 1];
                taggedPlayers[taggedPlayerCount - 1] = null;
                taggedPlayerCount--;
                break;
            }
        }
    }

    // 新增：清空所有标记的玩家
    private void ClearAllTaggedPlayers()
    {
        for (int i = 0; i < taggedPlayers.Length; i++)
        {
            taggedPlayers[i] = null;
        }
        taggedPlayerCount = 0;
    }

    private void EnterScanning()
    {
        currentState = StateScanning;
        stateStartTime = Time.time;
        trackedPlayer = null;
        if (laserLine != null)
        {
            laserLine.enabled = false;
        }
        // 扫描阶段：探照灯为白色
        if (spotLight != null)
        {
            spotLight.enabled = true;
            spotLight.color = Color.white;
        }

        // 停止黄灯音效（如果正在播放）
        StopYellowLightAudio();

        // 清空所有标记的玩家
        ClearAllTaggedPlayers();

        // 设置新的随机目标
        PickNewScanTarget();
        nextRetargetTime = Time.time + newPointInterval;
    }

    private void TickScanning()
    {
        // 旋转朝向随机目标
        AimTowards(currentScanTarget, scanTurnSpeedDegPerSec);

        // 时间到则换新点
        if (Time.time >= nextRetargetTime)
        {
            PickNewScanTarget();
            nextRetargetTime = Time.time + newPointInterval;
        }

        // 尝试检测玩家
        VRCPlayerApi candidate = FindPlayerInConeAndSight();
        if (candidate != null)
        {
            trackedPlayer = candidate;
            EnterHolding();
        }
    }

    private void EnterHolding()
    {
        currentState = StateHolding;
        stateStartTime = Time.time;
        // 停止移动：不再改变朝向
        // 发现玩家：探照灯变为黄色
        if (spotLight != null)
        {
            spotLight.enabled = true;
            spotLight.color = Color.yellow;
        }
        
        // 播放黄灯音效（仅播放一次）
        PlayYellowLightAudio();
    }

    /// <summary>
    /// 检查玩家是否在安全遮挡物后面
    /// </summary>
    public bool IsPlayerBehindSafeObstacle(VRCPlayerApi player)
    {
        if (!enableSafeObstacles || safeObstacles == null || player == null || !player.IsValid())
        {
            if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
            {
                Debug.Log($"[ShootCube] 安全遮挡物检查失败: enableSafeObstacles={enableSafeObstacles}, safeObstacles={(safeObstacles != null ? safeObstacles.Length : 0)}, player={(player != null ? player.displayName : "null")}");
            }
            return false;
        }
        
        Vector3 origin = scanPivot != null ? scanPivot.position : transform.position;
        Vector3 aimPoint = GetPlayerAimPoint(player);
        
        // 检查从炮台到玩家的射线是否命中安全遮挡物
        Vector3 direction = (aimPoint - origin).normalized;
        float distance = Vector3.Distance(origin, aimPoint);
        
        // 使用专门的遮挡物检测层掩码，确保能检测到所有可能的遮挡物
        LayerMask safeObstacleMask = -1; // 检测所有层
        
        RaycastHit[] hits = Physics.RaycastAll(origin, direction, distance, safeObstacleMask, QueryTriggerInteraction.Ignore);
        
        if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
        {
            Debug.Log($"[ShootCube] 安全遮挡物检测: 从 {origin} 到 {aimPoint}, 距离 {distance:F2}m, 射线命中数量: {(hits != null ? hits.Length : 0)}");
        }
        
        if (hits == null || hits.Length == 0)
        {
            return false;
        }
        
        // 按距离排序，找到最近的遮挡物
        // UdonSharp不支持Lambda表达式，使用传统排序方法
        for (int i = 0; i < hits.Length - 1; i++)
        {
            for (int j = i + 1; j < hits.Length; j++)
            {
                if (hits[i].distance > hits[j].distance)
                {
                    RaycastHit temp = hits[i];
                    hits[i] = hits[j];
                    hits[j] = temp;
                }
            }
        }
        
        for (int i = 0; i < hits.Length; i++)
        {
            Transform hitT = hits[i].transform;
            if (hitT == null) continue;
            
            if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
            {
                Debug.Log($"[ShootCube] 射线命中物体: {hitT.name} (层级: {LayerMask.LayerToName(hitT.gameObject.layer)}), 距离: {hits[i].distance:F2}m");
            }
            
            // 检查是否为安全遮挡物
            for (int j = 0; j < safeObstacles.Length; j++)
            {
                if (safeObstacles[j] != null && (hitT == safeObstacles[j] || hitT.IsChildOf(safeObstacles[j])))
                {
                    if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
                    {
                        Debug.Log($"[ShootCube] 玩家 {player.displayName} 被安全遮挡物 {hitT.name} 保护！");
                    }
                    return true;
                }
            }
        }
        
        if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
        {
            Debug.Log($"[ShootCube] 玩家 {player.displayName} 没有被安全遮挡物保护");
        }
        
        return false;
    }

    private void TickHolding()
    {
        if (!IsPlayerStillLit(trackedPlayer))
        {
            EnterScanning();
            return;
        }

        // 持续足够时间则进入激光锁定
        if (Time.time - stateStartTime >= requiredHoldSeconds)
        {
            EnterLaser();
        }
    }

    private void EnterLaser()
    {
        currentState = StateLaser;
        stateStartTime = Time.time;
        
        // 注意：玩家在子弹发射时才被标记，而不是在激光锁定时就标记
        
        if (laserLine != null)
        {
            laserLine.enabled = true;
            if (laserLine.positionCount != 2) laserLine.positionCount = 2;
            Vector3 startPoint = muzzlePoint != null ? muzzlePoint.position : (scanPivot != null ? scanPivot.position : transform.position);
            Vector3 playerPoint = trackedPlayer != null ? GetPlayerAimPoint(trackedPlayer) : startPoint + (scanPivot != null ? scanPivot.forward : transform.forward) * 2f;
            laserLine.SetPosition(0, startPoint);
            laserLine.SetPosition(1, playerPoint);
            if (laserLine.material != null && laserLine.material.HasProperty("_Color"))
            {
                laserLine.material.color = Color.red;
            }
            laserLine.startColor = Color.red;
            laserLine.endColor = Color.red;
            laserLine.startWidth = laserWidth;
            laserLine.endWidth = laserWidth;
        }
        // 激光阶段：关闭探照灯
        if (spotLight != null)
        {
            spotLight.enabled = false;
        }
        
        // 停止黄灯音效（进入激光阶段）
        StopYellowLightAudio();
    }

    private void TickLaser()
    {
        if (trackedPlayer == null || !trackedPlayer.IsValid())
        {
            EnterScanning();
            return;
        }

        // 激光指向玩家（此阶段允许轻微追踪）
        Vector3 playerPoint = GetPlayerAimPoint(trackedPlayer);
        Vector3 startPoint = muzzlePoint != null ? muzzlePoint.position : scanPivot.position;
        Vector3 direction = (playerPoint - startPoint).normalized;

        if (laserLine != null)
        {
            laserLine.SetPosition(0, startPoint);
            laserLine.SetPosition(1, playerPoint);
            // 保证激光是红色（若材质支持颜色）
            if (laserLine.material != null && laserLine.material.HasProperty("_Color"))
            {
                laserLine.material.color = Color.red;
            }
            laserLine.startColor = Color.red;
            laserLine.endColor = Color.red;
        }

        // 激光持续指向玩家一段时间
        if (Time.time - stateStartTime >= laserDurationSeconds)
        {
            // 激光结束时发射一次
            Fire(startPoint, direction);
            EnterCooldown();
        }
    }

    private void EnterCooldown()
    {
        currentState = StateCooldown;
        stateStartTime = Time.time;
        // 冷却阶段：关闭激光与探照灯
        if (laserLine != null)
        {
            laserLine.enabled = false;
        }
        if (spotLight != null)
        {
            spotLight.enabled = false;
        }
    }

    private void TickCooldown()
    {
        if (Time.time - stateStartTime >= cooldownAfterLaserSeconds)
        {
            EnterScanning();
        }
    }

    private void AimTowards(Vector3 worldTarget, float turnSpeedDegPerSec)
    {
        Vector3 direction = worldTarget - scanPivot.position;
        if (direction.sqrMagnitude < 0.0001f)
        {
            return;
        }
        Quaternion targetRotation = Quaternion.LookRotation(direction.normalized, Vector3.up);
        scanPivot.rotation = Quaternion.RotateTowards(
            scanPivot.rotation,
            targetRotation,
            turnSpeedDegPerSec * Time.deltaTime
        );
    }

    private void PickNewScanTarget()
    {
        // 在水平面上于scanRadius内随机一点
        Vector2 rand = Random.insideUnitCircle * scanRadius;
        Vector3 basePos = scanPivot.position;
        currentScanTarget = new Vector3(basePos.x + rand.x, basePos.y, basePos.z + rand.y);
    }

    private float GetEffectiveFovDeg()
    {
        if (fieldOfViewDegOverride > 0f)
        {
            return fieldOfViewDegOverride;
        }
        return spotLight != null ? spotLight.spotAngle : 45f;
    }

    private VRCPlayerApi FindPlayerInConeAndSight()
    {
        int count = VRCPlayerApi.GetPlayerCount();
        if (count <= 0)
        {
            return null;
        }

        VRCPlayerApi.GetPlayers(playersBuffer);
        int filled = VRCPlayerApi.GetPlayerCount();
        if (filled <= 0)
        {
            return null;
        }

        Vector3 origin = scanPivot.position;
        Vector3 forward = scanPivot.forward;
        float maxDistance = scanRadius;
        float halfFov = GetEffectiveFovDeg() * 0.5f;

        VRCPlayerApi closest = null;
        float closestSqr = float.MaxValue;

        for (int i = 0; i < filled; i++)
        {
            VRCPlayerApi p = playersBuffer[i];
            if (p == null || !p.IsValid())
            {
                continue;
            }

            Vector3 aimPoint = GetPlayerAimPoint(p);
            Vector3 toPlayer = aimPoint - origin;
            float distance = toPlayer.magnitude;
            if (distance > maxDistance)
            {
                continue;
            }

            float ang = Vector3.Angle(forward, toPlayer);
            if (ang > halfFov)
            {
                continue;
            }

            // 优先检查安全遮挡物 - 如果玩家在安全遮挡物后面，直接跳过
            if (enableSafeObstacles && this.IsPlayerBehindSafeObstacle(p))
            {
                if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
                {
                    Debug.Log($"[ShootCube] 玩家 {p.displayName} 在安全遮挡物后面，完全安全，跳过检测");
                }
                continue;
            }

            // 视线遮挡检查：忽略自身碰撞体
            if (!HasClearLineOfSight(origin, aimPoint))
            {
                // 调试信息：输出被遮挡的玩家
                if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
                {
                    Debug.Log($"[ShootCube] 玩家 {p.displayName} 被障碍物遮挡，跳过检测");
                }
                continue;
            }

            // 调试信息：输出找到的玩家
            if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
            {
                Debug.Log($"[ShootCube] 找到玩家 {p.displayName} - 距离: {distance:F2}m, 角度: {ang:F1}°, 视线清晰");
            }

            float sqr = toPlayer.sqrMagnitude;
            if (sqr < closestSqr)
            {
                closestSqr = sqr;
                closest = p;
            }
        }

        return closest;
    }

    private bool IsPlayerStillLit(VRCPlayerApi player)
    {
        if (player == null || !player.IsValid())
        {
            return false;
        }

        Vector3 origin = scanPivot.position;
        Vector3 forward = scanPivot.forward;
        Vector3 aimPoint = GetPlayerAimPoint(player);
        Vector3 toPlayer = aimPoint - origin;

        if (toPlayer.magnitude > scanRadius)
        {
            return false;
        }

        float ang = Vector3.Angle(forward, toPlayer);
        if (ang > GetEffectiveFovDeg() * 0.5f)
        {
            return false;
        }

        // 优先检查安全遮挡物 - 如果玩家在安全遮挡物后面，直接返回false
        if (enableSafeObstacles && this.IsPlayerBehindSafeObstacle(player))
        {
            if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
            {
                Debug.Log($"[ShootCube] 玩家 {player.displayName} 现在在安全遮挡物后面，停止跟踪");
            }
            return false;
        }

        // 视线遮挡（忽略自身）
        if (!HasClearLineOfSight(origin, aimPoint))
        {
            return false;
        }

        return true;
    }

    private Vector3 GetPlayerAimPoint(VRCPlayerApi player)
    {
        if (aimAtBody)
        {
            Vector3 bodyPoint;
            if (TryGetBodyPoint(player, preferredBodyBone, out bodyPoint))
            {
                return bodyPoint;
            }
            // 常见备选骨骼顺序
            if (TryGetBodyPoint(player, HumanBodyBones.UpperChest, out bodyPoint)) return bodyPoint;
            if (TryGetBodyPoint(player, HumanBodyBones.Chest, out bodyPoint)) return bodyPoint;
            if (TryGetBodyPoint(player, HumanBodyBones.Spine, out bodyPoint)) return bodyPoint;
            if (TryGetBodyPoint(player, HumanBodyBones.Hips, out bodyPoint)) return bodyPoint;
            // 最终回退：玩家位置 + 身体高度偏移
            return player.GetPosition() + Vector3.up * bodyAimHeightOffset;
        }

        // 瞄准头部/摄像机（默认旧逻辑）
        VRCPlayerApi.TrackingData head = player.GetTrackingData(VRCPlayerApi.TrackingDataType.Head);
        Vector3 point = head.position;
        if (point.sqrMagnitude < 0.0001f)
        {
            point = player.GetPosition() + Vector3.up * 1.5f;
        }
        return point;
    }

    private bool TryGetBodyPoint(VRCPlayerApi player, HumanBodyBones bone, out Vector3 pos)
    {
        pos = Vector3.zero;
        // 从玩家的人形骨骼获取世界坐标；若不可用将返回近似零向量
        Vector3 p = player.GetBonePosition(bone);
        if (p.sqrMagnitude > 0.0001f)
        {
            pos = p;
            return true;
        }
        return false;
    }

    private void Fire(Vector3 startPoint, Vector3 direction)
    {
        if (projectilePool == null || projectilePool.Length == 0)
        {
            return;
        }

        // 在子弹发射时，将当前被锁定的玩家添加到标记列表
        if (trackedPlayer != null && trackedPlayer.IsValid())
        {
            AddTaggedPlayer(trackedPlayer);
        }

        nextProjectileIndex++;
        if (nextProjectileIndex >= projectilePool.Length)
        {
            nextProjectileIndex = 0;
        }

        Rigidbody body = projectilePool[nextProjectileIndex];
        if (body == null)
        {
            return;
        }

        GameObject go = body.gameObject;

        // 争取该物体所有权
        if (Networking.LocalPlayer != null)
        {
            Networking.SetOwner(Networking.LocalPlayer, go);
        }

        // 重置并发射
        Transform t = body.transform;
        t.position = startPoint;
        t.rotation = Quaternion.LookRotation(direction, Vector3.up);

        // 激活对象（若在对象池中被禁用）
        if (!go.activeSelf)
        {
            go.SetActive(true);
        }

        body.velocity = Vector3.zero;
        body.angularVelocity = Vector3.zero;
        body.AddForce(direction * projectileSpeed, ForceMode.VelocityChange);

        // 标记本体处于"活跃"以便命中检测与寿命
        if (projectileActiveFlags != null && nextProjectileIndex < projectileActiveFlags.Length)
        {
            projectileActiveFlags[nextProjectileIndex] = true;
            projectileFiredTimes[nextProjectileIndex] = Time.time;
        }

        // 播放发射音效
        PlayFireAudio();
    }

    // 本地命中检测：当"活跃"的子弹接近本地玩家的身体瞄准点时，清空生命值
    private void TickProjectileHitDetection()
    {
        if (!killOnProjectileHit)
        {
            return;
        }
        if (projectilePool == null || projectilePool.Length == 0 || projectileActiveFlags == null)
        {
            return;
        }
        VRCPlayerApi local = Networking.LocalPlayer;
        if (local == null)
        {
            return;
        }

        // 检查本地玩家是否在被标记的玩家列表中
        if (!IsPlayerTagged(local))
        {
            return; // 只有被标记的玩家才会被击杀
        }

        // 计算本地玩家身体瞄准点
        Vector3 playerPoint;
        if (aimAtBody)
        {
            if (!TryGetBodyPoint(local, preferredBodyBone, out playerPoint))
            {
                if (!TryGetBodyPoint(local, HumanBodyBones.UpperChest, out playerPoint) &&
                    !TryGetBodyPoint(local, HumanBodyBones.Chest, out playerPoint) &&
                    !TryGetBodyPoint(local, HumanBodyBones.Spine, out playerPoint) &&
                    !TryGetBodyPoint(local, HumanBodyBones.Hips, out playerPoint))
                {
                    playerPoint = local.GetPosition() + Vector3.up * bodyAimHeightOffset;
                }
            }
        }
        else
        {
            VRCPlayerApi.TrackingData head = local.GetTrackingData(VRCPlayerApi.TrackingDataType.Head);
            playerPoint = head.position.sqrMagnitude > 0.0001f ? head.position : (local.GetPosition() + Vector3.up * 1.5f);
        }

        float now = Time.time;
        for (int i = 0; i < projectilePool.Length; i++)
        {
            if (!projectileActiveFlags[i])
            {
                continue;
            }

            Rigidbody rb = projectilePool[i];
            if (rb == null)
            {
                projectileActiveFlags[i] = false;
                continue;
            }

            // 超时处理
            if (projectileLifeSeconds > 0f && now - projectileFiredTimes[i] > projectileLifeSeconds)
            {
                projectileActiveFlags[i] = false;
                continue;
            }

            // 简化的命中检测：使用距离检测
            float dist = Vector3.Distance(rb.position, playerPoint);
            if (dist <= projectileHitRadius)
            {
                // 清空生命值
                if (worldHealth != null)
                {
                    worldHealth.InstantlyKillPlayer();
                }

                // 处理子弹
                projectileActiveFlags[i] = false;
                if (deactivateProjectileOnHit)
                {
                    GameObject go = rb.gameObject;
                    if (go.activeSelf)
                    {
                        go.SetActive(false);
                    }
                }
            }
        }
    }

    // 判断从 origin 到 target 的直线是否无遮挡（忽略自身层级的碰撞体）
    private bool HasClearLineOfSight(Vector3 origin, Vector3 target)
    {
        float distance = Vector3.Distance(origin, target);
        if (distance <= 0.001f)
        {
            return true;
        }
        
        Vector3 dir = (target - origin).normalized;
        
        // 调试信息：输出射线检测参数
        if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
        {
            Debug.Log($"[ShootCube] 射线检测: 起点 {origin}, 终点 {target}, 距离 {distance:F2}m, 方向 {dir}");
            Debug.Log($"[ShootCube] obstructionMask: {obstructionMask.value}");
        }
        
        RaycastHit[] hits = Physics.RaycastAll(origin, dir, distance, obstructionMask, QueryTriggerInteraction.Ignore);
        
        if (hits == null || hits.Length == 0)
        {
            if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
            {
                Debug.Log($"[ShootCube] 射线检测无遮挡，视线清晰");
            }
            return true;
        }
        
        // 按距离排序，找到最近的遮挡物
        // UdonSharp不支持Lambda表达式，使用传统排序方法
        for (int i = 0; i < hits.Length - 1; i++)
        {
            for (int j = i + 1; j < hits.Length; j++)
            {
                if (hits[i].distance > hits[j].distance)
                {
                    RaycastHit temp = hits[i];
                    hits[i] = hits[j];
                    hits[j] = temp;
                }
            }
        }
        
        for (int i = 0; i < hits.Length; i++)
        {
            Transform hitT = hits[i].transform;
            if (hitT == null) continue;
            
            if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
            {
                Debug.Log($"[ShootCube] 射线命中遮挡物: {hitT.name} (层级: {LayerMask.LayerToName(hitT.gameObject.layer)}), 距离: {hits[i].distance:F2}m");
            }
            
            // 检查是否为安全遮挡物
            if (enableSafeObstacles && safeObstacles != null)
            {
                for (int j = 0; j < safeObstacles.Length; j++)
                {
                    if (safeObstacles[j] != null && (hitT == safeObstacles[j] || hitT.IsChildOf(safeObstacles[j])))
                    {
                        if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
                        {
                            Debug.Log($"[ShootCube] 检测到安全遮挡物 {hitT.name}，视线被安全遮挡");
                        }
                        return false; // 安全遮挡物会阻挡视线
                    }
                }
            }
            
            // 检查是否为末端容忍距离（可能是玩家身体）
            if (hits[i].distance >= distance - losEndAllowance) // Changed from endTolerance to losEndAllowance
            {
                if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
                {
                    Debug.Log($"[ShootCube] 遮挡物在末端容忍距离内，视为无遮挡");
                }
                return true;
            }
            
            // 普通遮挡物阻挡视线
            if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
            {
                Debug.Log($"[ShootCube] 普通遮挡物 {hitT.name} 阻挡视线");
            }
            return false;
        }
        
        return true;
    }

#if UNITY_EDITOR
    // 调试方法：手动测试视线遮挡
    public void DebugLineOfSight()
    {
        if (Networking.LocalPlayer == null || !Networking.LocalPlayer.IsOwner(gameObject))
        {
            Debug.Log("[ShootCube] 只有炮台所有者才能执行调试");
            return;
        }

        VRCPlayerApi localPlayer = Networking.LocalPlayer;
        Vector3 origin = scanPivot != null ? scanPivot.position : transform.position;
        Vector3 target = localPlayer.GetPosition();
        
        Debug.Log($"[ShootCube] === 视线遮挡调试 ===");
        Debug.Log($"[ShootCube] 炮台位置: {origin}");
        Debug.Log($"[ShootCube] 玩家位置: {target}");
        Debug.Log($"[ShootCube] 阻挡层掩码: {obstructionMask.value} (二进制: {IntToBinaryString(obstructionMask.value)})");
        Debug.Log($"[ShootCube] 玩家层级: 无法获取 (Udon限制)");
        
        // 测试射线检测
        bool hasClearSight = HasClearLineOfSight(origin, target);
        Debug.Log($"[ShootCube] 视线检测结果: {(hasClearSight ? "清晰" : "被遮挡")}");
        Debug.Log($"[ShootCube] 距离: {Vector3.Distance(origin, target):F2}m");
        Debug.Log($"[ShootCube] losEndAllowance: {losEndAllowance:F2}m");
        Debug.Log($"[ShootCube] =========================");
    }
    
    /// <summary>
    /// 重新计算阻挡层掩码（可在运行时调用）
    /// </summary>
    public void RecalculateObstructionMask()
    {
        if (autoExcludePlayerLayers)
        {
            obstructionMask = ~((1 << 8) | (1 << 0)); // 排除玩家层和默认层
        }
        else
        {
            obstructionMask = manualObstructionMask;
        }
        
        if (Networking.LocalPlayer != null && Networking.LocalPlayer.IsOwner(gameObject))
        {
            Debug.Log($"[ShootCube] 阻挡层掩码已更新: {obstructionMask.value} (二进制: {IntToBinaryString(obstructionMask.value)})");
        }
    }
    
    /// <summary>
    /// 调试遮挡物检测 - 在控制台输出详细信息
    /// </summary>
    public void DebugOcclusionDetection()
    {
        if (Networking.LocalPlayer == null || !Networking.LocalPlayer.IsOwner(gameObject))
        {
            Debug.Log("[ShootCube] 只有物体拥有者才能调试遮挡物检测");
            return;
        }
        
        Debug.Log("=== 遮挡物检测调试信息 ===");
        Debug.Log($"enableSafeObstacles: {enableSafeObstacles}");
        Debug.Log($"safeObstacles 数量: {(safeObstacles != null ? safeObstacles.Length : 0)}");
        
        if (safeObstacles != null)
        {
            for (int i = 0; i < safeObstacles.Length; i++)
            {
                if (safeObstacles[i] != null)
                {
                    Debug.Log($"  遮挡物 {i}: {safeObstacles[i].name} (层级: {LayerMask.LayerToName(safeObstacles[i].gameObject.layer)})");
                }
                else
                {
                    Debug.Log($"  遮挡物 {i}: null");
                }
            }
        }
        
        Debug.Log($"obstructionMask: {obstructionMask.value}");
        Debug.Log($"autoExcludePlayerLayers: {autoExcludePlayerLayers}");
        Debug.Log($"manualObstructionMask: {manualObstructionMask.value}");
        
        // 检查当前扫描的玩家
        if (trackedPlayer != null && trackedPlayer.IsValid())
        {
            Debug.Log($"当前跟踪的玩家: {trackedPlayer.displayName}");
            bool isBehindSafeObstacle = this.IsPlayerBehindSafeObstacle(trackedPlayer);
            Debug.Log($"该玩家是否在安全遮挡物后面: {isBehindSafeObstacle}");
        }
        
        Debug.Log("=== 调试信息结束 ===");
    }
    
    /// <summary>
    /// 强制重新计算阻挡层掩码
    /// </summary>
    public void ForceRecalculateObstructionMask()
    {
        RecalculateObstructionMask();
        Debug.Log($"[ShootCube] 强制重新计算阻挡层掩码完成: {obstructionMask.value}");
    }
    
    /// <summary>
    /// 获取当前阻挡层掩码的详细信息
    /// </summary>
    public string GetObstructionMaskInfo()
    {
        string info = $"阻挡层掩码值: {obstructionMask.value}\n";
        info += $"二进制表示: {IntToBinaryString(obstructionMask.value)}\n";
        info += $"包含的层级: ";
        
        for (int i = 0; i < 32; i++)
        {
            if (((1 << i) & obstructionMask.value) != 0)
            {
                string layerName = LayerMask.LayerToName(i);
                if (string.IsNullOrEmpty(layerName))
                {
                    layerName = $"Layer{i}";
                }
                info += $"{layerName}({i}) ";
            }
        }
        
        return info;
    }
    
    /// <summary>
    /// 将整数转换为二进制字符串（UdonSharp兼容）
    /// </summary>
    private string IntToBinaryString(int value)
    {
        string result = "";
        for (int i = 31; i >= 0; i--)
        {
            if (((1 << i) & value) != 0)
            {
                result += "1";
            }
            else
            {
                result += "0";
            }
            
            // 每8位添加一个空格，便于阅读
            if (i % 8 == 0 && i > 0)
            {
                result += " ";
            }
        }
        return result;
    }

    private void OnDrawGizmosSelected()
    {
        // 仅编辑器下绘制可视化
        Transform pivot = scanPivot != null ? scanPivot : (spotLight != null ? spotLight.transform : transform);
        if (pivot == null)
        {
            return;
        }

        // 绘制扫描半径水平圆环
        if (drawScanRadiusGizmo && scanRadius > 0.01f)
        {
            Color old = Gizmos.color;
            Gizmos.color = gizmoRadiusColor;
            Vector3 center = pivot.position;
            float radius = scanRadius;
            int seg = gizmoCircleSegments <= 0 ? 64 : gizmoCircleSegments;
            Vector3 prev = center + new Vector3(radius, 0f, 0f);
            for (int i = 1; i <= seg; i++)
            {
                float ang = (float)i / seg * Mathf.PI * 2f;
                Vector3 next = center + new Vector3(Mathf.Cos(ang) * radius, 0f, Mathf.Sin(ang) * radius);
                Gizmos.DrawLine(prev, next);
                prev = next;
            }
            Gizmos.color = old;
        }

        // 绘制水平视角两条边界线
        if (drawFovGizmo)
        {
            float halfFov = (fieldOfViewDegOverride > 0f ? fieldOfViewDegOverride : (spotLight != null ? spotLight.spotAngle : 45f)) * 0.5f;
            Vector3 origin = pivot.position;
            Vector3 forward = pivot.forward;
            Vector3 right = Vector3.Cross(Vector3.up, Vector3.Cross(forward, Vector3.up)).normalized; // 水平右方向
            if (right.sqrMagnitude < 0.0001f)
            {
                right = Vector3.right;
            }
            Quaternion rotRight = Quaternion.AngleAxis(halfFov, Vector3.up);
            Quaternion rotLeft = Quaternion.AngleAxis(-halfFov, Vector3.up);
            Vector3 dirRight = rotRight * forward;
            Vector3 dirLeft = rotLeft * forward;

            Color old = Gizmos.color;
            Gizmos.color = gizmoFovColor;
            Gizmos.DrawLine(origin, origin + dirRight.normalized * scanRadius);
            Gizmos.DrawLine(origin, origin + dirLeft.normalized * scanRadius);
            Gizmos.color = old;
        }

        // 绘制命中半径球（用于可视化 projectileHitRadius）。为避免Udon限制，不区分运行/编辑模式
        if (drawHitRadiusGizmo)
        {
            Color old = Gizmos.color;
            Gizmos.color = gizmoHitRadiusColor;
            Vector3 center = debugHitPoint != null ? debugHitPoint.position : pivot.position;
            Gizmos.DrawWireSphere(center, Mathf.Max(0.01f, projectileHitRadius));
            Gizmos.color = old;
        }

        // 在每个对象池子弹位置绘制命中半径（便于观察是否能触达玩家）
        if (drawHitRadiusOnProjectiles && projectilePool != null)
        {
            Color old = Gizmos.color;
            Gizmos.color = gizmoHitRadiusOnProjectileColor;
            for (int i = 0; i < projectilePool.Length; i++)
            {
                Rigidbody rb = projectilePool[i];
                if (rb == null) continue;
                Gizmos.DrawWireSphere(rb.position, Mathf.Max(0.01f, projectileHitRadius));
            }
            Gizmos.color = old;
        }

        // 绘制黄灯音效范围可视化
        if (showYellowLightAudioRange && yellowLightAudioSource != null)
        {
            Color old = Gizmos.color;
            Gizmos.color = yellowLightAudioRangeColor;
            Vector3 audioCenter = yellowLightAudioSource.transform.position;
            
            // 绘制最大听音范围（外圈）
            Gizmos.DrawWireSphere(audioCenter, yellowLightAudioMaxDistance);
            
            // 绘制最小听音范围（内圈）- 使用稍微不同的透明度
            Color innerColor = yellowLightAudioRangeColor;
            innerColor.a = yellowLightAudioRangeColor.a * 0.6f;
            Gizmos.color = innerColor;
            Gizmos.DrawWireSphere(audioCenter, yellowLightAudioMinDistance);
            
            Gizmos.color = old;
        }

        // 绘制发射音效范围可视化
        if (showFireAudioRange && fireAudioSource != null)
        {
            Color old = Gizmos.color;
            Gizmos.color = fireAudioRangeColor;
            Vector3 fireAudioCenter = fireAudioSource.transform.position;
            
            // 绘制最大听音范围（外圈）
            Gizmos.DrawWireSphere(fireAudioCenter, fireAudioMaxDistance);
            
            // 绘制最小听音范围（内圈）- 使用稍微不同的透明度
            Color innerFireColor = fireAudioRangeColor;
            innerFireColor.a = fireAudioRangeColor.a * 0.6f;
            Gizmos.color = innerFireColor;
            Gizmos.DrawWireSphere(fireAudioCenter, fireAudioMinDistance);
            
            Gizmos.color = old;
        }
    }
#endif
}
